/**
 * 帧渲染器 - 负责动画循环和弹幕帧更新
 */
import type { ActiveBarrage, BarrageConfig, DetectionArea } from '../../types'
import type { BarrageDrawer } from './BarrageDrawer'
import type { FeatureIntegration } from '../integrations/FeatureIntegration'

/**
 * 帧渲染回调接口
 */
export interface FrameRenderCallbacks {
  /** 移除弹幕回调 */
  onRemoveBarrage: (id: string) => void
  /** 渲染调试信息回调 */
  onRenderDebug: () => void
  /** 获取活跃弹幕列表 */
  getActiveBarrages: () => ActiveBarrage[]
  /** 获取配置 */
  getConfig: () => BarrageConfig
}

/**
 * 帧渲染器配置
 */
export interface FrameRendererOptions {
  video?: HTMLVideoElement
  barrageDrawer: BarrageDrawer
  featureIntegration: FeatureIntegration
  callbacks: FrameRenderCallbacks
}

/**
 * 帧渲染器类
 */
export class FrameRenderer {
  private video?: HTMLVideoElement
  private barrageDrawer: BarrageDrawer
  private featureIntegration: FeatureIntegration
  private callbacks: FrameRenderCallbacks

  private animationFrameId = 0
  private lastTimestamp = 0
  private isPaused = false
  private isDestroyed = false

  // 状态
  private detectionAreas: DetectionArea[] = []
  private fallbackMode = false
  private fallbackOpacity = 0.6

  constructor(options: FrameRendererOptions) {
    this.video = options.video
    this.barrageDrawer = options.barrageDrawer
    this.featureIntegration = options.featureIntegration
    this.callbacks = options.callbacks
  }

  /**
   * 更新视频元素
   */
  updateVideo(video?: HTMLVideoElement): void {
    this.video = video
  }

  /**
   * 启动渲染循环
   */
  start(): void {
    if (this.animationFrameId !== 0) {
      return // 已经在运行
    }

    const loop = (timestamp: number) => {
      if (this.isDestroyed) return
      
      this.animationFrameId = requestAnimationFrame(loop)
      this.renderFrame(timestamp)
    }
    
    this.animationFrameId = requestAnimationFrame(loop)
  }

  /**
   * 停止渲染循环
   */
  stop(): void {
    if (this.animationFrameId !== 0) {
      cancelAnimationFrame(this.animationFrameId)
      this.animationFrameId = 0
    }
  }

  /**
   * 暂停渲染
   */
  pause(): void {
    this.isPaused = true
  }

  /**
   * 恢复渲染
   */
  resume(): void {
    this.isPaused = false
  }

  /**
   * 销毁渲染器
   */
  destroy(): void {
    this.isDestroyed = true
    this.stop()
  }

  /**
   * 渲染单帧
   */
  private renderFrame(timestamp: number): void {
    // 从回调获取最新状态
    const activeBarrages = this.callbacks.getActiveBarrages()
    const config = this.callbacks.getConfig()

    // 获取视频播放速度
    const playbackRate = this.video?.playbackRate || 1
    const delta = this.isPaused ? 0 : (timestamp - this.lastTimestamp) * playbackRate
    this.lastTimestamp = timestamp

    // 强制清空画布，防止残留
    this.barrageDrawer.forceCleanCanvas()

    // 更新和渲染弹幕
    const toRemove: string[] = []

    activeBarrages.forEach(barrage => {
      // 更新位置
      if (delta > 0) {
        barrage.x -= (barrage.speed / 1000) * delta
      }

      // 检查是否需要移除
      if (barrage.x + barrage.width < 0) {
        toRemove.push(barrage.id)
        return
      }

      // 渲染弹幕（先不考虑遮挡，全部正常绘制）
      this.barrageDrawer.renderBarrage(barrage, config, this.fallbackMode, this.fallbackOpacity)
    })

    // 移除超出屏幕的弹幕
    toRemove.forEach(id => this.callbacks.onRemoveBarrage(id))

    // 应用人物蒙版（擦除人物覆盖的弹幕部分）
    if (config.faceDetection) {
      this.detectionAreas = this.featureIntegration.processPoseDetection(timestamp)
      this.barrageDrawer.applyPersonMask(this.detectionAreas)
      
      // 🆕 绘制骨架线（在蒙版之后绘制，这样骨架线不会被遮挡）
      if (config.showSkeleton !== false && this.detectionAreas.length > 0) {
        this.renderSkeletonOverlay(this.detectionAreas, config)
      }
    } else {
      this.detectionAreas = []
    }

    // 渲染调试信息
    if (config.debug) {
      this.callbacks.onRenderDebug()
    }
  }

  /**
   * 绘制骨架线覆盖层
   */
  private renderSkeletonOverlay(detectionAreas: DetectionArea[], config: BarrageConfig): void {
    // 调用 BarrageDrawer 的公开方法绘制骨架线
    this.barrageDrawer.renderDetectionAreas(detectionAreas, config)
  }

  /**
   * 获取检测区域
   */
  getDetectionAreas(): DetectionArea[] {
    return this.detectionAreas
  }

  /**
   * 设置备用模式
   */
  setFallbackMode(enabled: boolean, opacity?: number): void {
    this.fallbackMode = enabled
    if (opacity !== undefined) {
      this.fallbackOpacity = opacity
    }
  }

  /**
   * 获取备用模式状态
   */
  isFallbackMode(): boolean {
    return this.fallbackMode
  }

  /**
   * 检查是否已暂停
   */
  isPausedState(): boolean {
    return this.isPaused
  }

  /**
   * 检查是否已销毁
   */
  isDestroyedState(): boolean {
    return this.isDestroyed
  }
}

